package com.candy.candylogservice.interceptor;

import com.candy.candycommon.utils.ApplicationContentUtils;
import com.candy.candylogservice.config.RpcLogProperties;
import com.candy.candylogservice.dto.LogLinkDTO;
import com.candy.candylogservice.queue.LogQueue;
import com.candy.candylogservice.service.LogLinkService;
import com.gitee.candy.number.SnowflakeIdGenerator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.util.StreamUtils;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author suYanLong
 * @date 2022年10月25日 14:57
 */
@Slf4j
public class LogInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        LogUtils.clear();

        LogLinkDTO logLinkDTO = new LogLinkDTO();
        //获取请求参数
        logLinkDTO.setRequestUrl(request.getRequestURL().toString());
        String queryString = request.getQueryString();
        log.info("请求参数:{}", queryString);
        SnowflakeIdGenerator snowflakeIdGenerator = new SnowflakeIdGenerator(1, 1);
        logLinkDTO.setId(snowflakeIdGenerator.nextId());
        logLinkDTO.setRequestParam(queryString);
        logLinkDTO.setTraceId(LogUtils.getTraceId());
        //获取请求body
        byte[] bodyBytes = StreamUtils.copyToByteArray(request.getInputStream());
        String body = new String(bodyBytes, request.getCharacterEncoding());
        logLinkDTO.setRequestBody(body);
        log.info("请求体：{}", body);
        logLinkDTO.setMethod(request.getMethod());

        String name = ApplicationContentUtils.getApplicationContext().getEnvironment().getProperty("spring.application.name");
        logLinkDTO.setServiceName(name);

        LogLinkService logLinkService = ApplicationContentUtils.getBean(LogLinkService.class);
        ThreadPoolTaskExecutor executor = (ThreadPoolTaskExecutor) ApplicationContentUtils.getApplicationContext().getBean("asyncTaskExecutor");
        executor.execute(() -> {
            RpcLogProperties rpcLogProperties = ApplicationContentUtils.getBean(RpcLogProperties.class);
            try {
                if (rpcLogProperties.getEnable()) {
                    if (rpcLogProperties.getEnableAsync()) {
                        LogQueue.logLinkQueue.add(logLinkDTO);
                    } else {
                        logLinkService.save(logLinkDTO);
                    }
                }
            } catch (Exception e) {
                LogQueue.logLinkQueue.add(logLinkDTO);
                log.error("日志服务异常！发送日志失败：批量：{} 日志数据：{}", rpcLogProperties.getEnableBatch(), logLinkDTO);
            }
        });
        LogUtils.setLog(logLinkDTO);
        return super.preHandle(request, response, handler);
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        super.afterCompletion(request, response, handler, ex);
    }

}
